using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using StudentManagement.Application.DTOs;
using StudentManagement.Application.Services;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace StudentManagement.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ScoreController : ControllerBase
    {
        private readonly IScoreService _scoreService;

        public ScoreController(IScoreService scoreService)
        {
            _scoreService = scoreService;
        }

        // GET: api/Score
        [HttpGet]
        [Authorize]
        public async Task<ActionResult<IEnumerable<ScoreDTO>>> GetAllScores()
        {
            var scores = await _scoreService.GetAllScoresAsync();
            return Ok(scores);
        }

        // GET: api/Score/{id}
        [HttpGet("{id}")]
        [Authorize]
        public async Task<ActionResult<ScoreDTO>> GetScoreById(int id)
        {
            var score = await _scoreService.GetScoreByIdAsync(id);
            if (score == null)
            {
                return NotFound();
            }
            return Ok(score);
        }

        // GET: api/Score/student/{studentId}
        [HttpGet("student/{studentId}")]
        [Authorize]
        public async Task<ActionResult<IEnumerable<ScoreDTO>>> GetScoresByStudentId(int studentId)
        {
            var scores = await _scoreService.GetScoresByStudentIdAsync(studentId);
            return Ok(scores);
        }

        // GET: api/Score/course/{courseId}
        [HttpGet("course/{courseId}")]
        [Authorize]
        public async Task<ActionResult<IEnumerable<ScoreDTO>>> GetScoresByCourseId(int courseId)
        {
            var scores = await _scoreService.GetScoresByCourseIdAsync(courseId);
            return Ok(scores);
        }

        // GET: api/Score/student/{studentId}/course/{courseId}
        [HttpGet("student/{studentId}/course/{courseId}")]
        [Authorize]
        public async Task<ActionResult<ScoreDTO>> GetScoreByStudentAndCourse(int studentId, int courseId)
        {
            var score = await _scoreService.GetScoreByStudentAndCourseAsync(studentId, courseId);
            if (score == null)
            {
                return NotFound();
            }
            return Ok(score);
        }

        // GET: api/Score/average/course/{courseId}
        [HttpGet("average/course/{courseId}")]
        [Authorize]
        public async Task<ActionResult<double>> GetAverageScoreByCourseId(int courseId)
        {
            var average = await _scoreService.GetAverageScoreByCourseIdAsync(courseId);
            return Ok(average);
        }

        // POST: api/Score
        [HttpPost]
        [Authorize(Roles = "Admin,Teacher")]
        public async Task<ActionResult<ScoreDTO>> CreateScore([FromBody] ScoreDTO scoreDTO)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var createdScore = await _scoreService.CreateScoreAsync(scoreDTO);
                return CreatedAtAction(nameof(GetScoreById), new { id = createdScore.Id }, createdScore);
            }
            catch (System.Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // PUT: api/Score/{id}
        [HttpPut("{id}")]
        [Authorize(Roles = "Admin,Teacher")]
        public async Task<ActionResult<ScoreDTO>> UpdateScore(int id, [FromBody] ScoreDTO scoreDTO)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var updatedScore = await _scoreService.UpdateScoreAsync(id, scoreDTO);
                if (updatedScore == null)
                {
                    return NotFound();
                }
                return Ok(updatedScore);
            }
            catch (System.Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // DELETE: api/Score/{id}
        [HttpDelete("{id}")]
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult> DeleteScore(int id)
        {
            try
            {
                await _scoreService.DeleteScoreAsync(id);
                return Ok();
            }
            catch (Exception ex)
            {
                return NotFound(ex.Message);
            }
        }

        // GET: api/Score/student-course-exists/{studentId}/{courseId}
        [HttpGet("student-course-exists/{studentId}/{courseId}")]
        [Authorize(Roles = "Admin,Teacher")]
        public async Task<ActionResult<bool>> ScoreExists(int studentId, int courseId)
        {
            try
            {
                await _scoreService.GetScoreByStudentAndCourseAsync(studentId, courseId);
                return Ok(true);
            }
            catch (Exception)
            {
                return Ok(false);
            }
        }
    }
}